#include "mtf.h"

#include <iostream>

using namespace mtf;
using namespace std;

MTF::MTF():Step(){

}

MTF::~MTF(){

}
/***
 * i stands for index
 * alphabet[i] stands for char 
 **/
void  MTF::initial(){
 for(uint32_t i=0;i<alphabet_size;i++)
   alphabet[i]=i;
}

void MTF::encode(uint8_t* in_buf,uint8_t* out_buf,uint32_t buf_size){
 initial();
 uint32_t j=0;
 for(uint32_t i=0;i<buf_size;i++){
   for(j=0;j<alphabet_size;j++){
      if(in_buf[i]==alphabet[j]){
         out_buf[i]=j;
         for(;j>0;j--){
             alphabet[j]=alphabet[j-1];
        }
         break;
      }
   } 
   alphabet[0]=in_buf[i];
 }
}

void MTF::decode(uint8_t* in_buf,uint8_t* out_buf,uint32_t buf_size){
 initial();
 uint32_t j=0;
 for(uint32_t i=0;i<buf_size;i++){
    out_buf[i]=alphabet[in_buf[i]];
    for(j=in_buf[i];j>0;j--){
       alphabet[j]=alphabet[j-1];
    }
    alphabet[0]=out_buf[i];
 }
}

void
MTF::encode(hzstream* hz){
	hz->out_size = hz->in_size; 
	hz->out_buf = new uint8_t[hz->out_size];
	this->encode(hz->in_buf,hz->out_buf,hz->in_size);
}

void
MTF::decode(hzstream* hz){
	hz->out_size = hz->in_size;
	hz->out_buf = new uint8_t[hz->out_size];
	this->decode(hz->in_buf,hz->out_buf,hz->in_size);
}
